from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import uuid


class BaseModel(models.Model):
    """基础模型，包含通用字段"""
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)
    created_by = models.ForeignKey(
        User, 
        on_delete=models.SET_NULL, 
        null=True, 
        blank=True,
        related_name='%(class)s_created',
        verbose_name='创建者'
    )
    
    class Meta:
        abstract = True


class Template(BaseModel):
    """模板配置模型"""
    name = models.CharField('模板名称', max_length=100, unique=True)
    description = models.TextField('模板描述', blank=True)
    is_active = models.BooleanField('是否启用', default=True)
    
    # 模板文件
    template_file = models.FileField('模板文件', upload_to='templates/', null=True, blank=True)
    
    # 模板类型
    TEMPLATE_TYPE_CHOICES = [
        ('tabular', '表格式模板'),  # 表头+数据行模式
        ('document', '单据式模板'),  # 单据格式
        ('mixed', '混合模板'),  # 混合格式
    ]
    template_type = models.CharField('模板类型', max_length=20, choices=TEMPLATE_TYPE_CHOICES, default='tabular')
    
    # 数据源配置
    DATA_SOURCE_TYPE_CHOICES = [
        ('single_file', '单文件处理'),
        ('multi_file', '多文件关联'),
        ('one_to_many', '一对多生成'),
    ]
    data_source_type = models.CharField('数据源类型', max_length=20, choices=DATA_SOURCE_TYPE_CHOICES, default='single_file')
    
    # Excel文件结构信息
    excel_structure = models.JSONField('Excel结构信息', default=dict, blank=True, help_text='存储Excel文件的表头、行列信息等')
    
    # 字段配置规则
    field_configs = models.JSONField('字段配置规则', default=dict, blank=True, help_text='存储每个字段的处理规则配置')
    
    # 多文件关联配置
    multi_file_config = models.JSONField('多文件关联配置', default=dict, blank=True, help_text='配置多文件间的关联规则')
    
    # 处理逻辑配置
    processing_logic = models.JSONField('处理逻辑配置', default=dict, blank=True, help_text='配置复杂的数据处理逻辑')
    
    # 输出配置
    output_config = models.JSONField('输出配置', default=dict, blank=True, help_text='配置输出格式和规则')
    
    # 原有配置信息（保持兼容性）
    mapping_config = models.JSONField('映射配置', default=dict, blank=True)
    fixed_config = models.JSONField('固定值配置', default=dict, blank=True)
    pol_config = models.JSONField('港口配置', default=dict, blank=True)
    shipper_config = models.JSONField('发货人配置', default=dict, blank=True)
    
    class Meta:
        verbose_name = '模板配置'
        verbose_name_plural = '模板配置'
        ordering = ['-created_at']
    
    def __str__(self):
        return self.name
    
    def get_field_config(self, field_name):
        """获取指定字段的配置"""
        return self.field_configs.get(field_name, {})
    
    def set_field_config(self, field_name, config):
        """设置指定字段的配置"""
        if not self.field_configs:
            self.field_configs = {}
        self.field_configs[field_name] = config
        self.save()


class FieldConfig(BaseModel):
    """字段配置模型"""
    template = models.ForeignKey(Template, on_delete=models.CASCADE, related_name='field_configs_rel')
    field_name = models.CharField('字段名称', max_length=100)
    source_column = models.CharField('源列名', max_length=100, blank=True)
    
    # 规则类型
    RULE_TYPE_CHOICES = [
        ('split', '拆分'),
        ('aggregate', '聚合'),
        ('deduplicate', '去重'),
        ('generate', '生成'),
        ('assign', '赋值'),
        ('transform', '转换'),
        ('lookup', '查找'),
        ('calculate', '计算'),
    ]
    rule_type = models.CharField('规则类型', max_length=20, choices=RULE_TYPE_CHOICES)
    
    # 拆分配置
    split_delimiter = models.CharField('拆分分隔符', max_length=10, blank=True)
    split_direction = models.CharField('拆分方向', max_length=20, blank=True, choices=[('horizontal', '水平'), ('vertical', '垂直')])
    
    # 聚合配置
    aggregate_method = models.CharField('聚合方法', max_length=20, blank=True, choices=[('sum', '求和'), ('avg', '平均'), ('count', '计数'), ('concat', '连接')])
    aggregate_separator = models.CharField('聚合分隔符', max_length=10, blank=True)
    
    # 去重配置
    deduplicate_scope = models.CharField('去重范围', max_length=20, blank=True, choices=[('column', '列内'), ('row', '行内'), ('global', '全局')])
    
    # 生成配置
    generate_pattern = models.CharField('生成模式', max_length=200, blank=True)
    generate_count = models.IntegerField('生成数量', null=True, blank=True)
    
    # 赋值配置
    assign_value = models.CharField('赋值内容', max_length=200, blank=True)
    assign_mode = models.CharField('赋值模式', max_length=20, blank=True, choices=[('fixed', '固定值'), ('formula', '公式'), ('lookup', '查找')])
    
    # 转换配置
    transform_rules = models.JSONField('转换规则', default=dict, blank=True)
    
    # 通用配置
    config_data = models.JSONField('配置数据', default=dict, blank=True)
    
    class Meta:
        db_table = 'core_field_config'
        verbose_name = '字段配置'
        verbose_name_plural = '字段配置'
        unique_together = ['template', 'field_name']


class ProcessingRule(BaseModel):
    """处理规则模型"""
    template = models.ForeignKey(Template, on_delete=models.CASCADE, related_name='processing_rules')
    rule_name = models.CharField('规则名称', max_length=100)
    rule_order = models.IntegerField('执行顺序', default=0)
    
    # 规则类型
    RULE_TYPE_CHOICES = [
        ('data_extraction', '数据提取'),
        ('field_mapping', '字段映射'),
        ('data_transformation', '数据转换'),
        ('data_validation', '数据验证'),
        ('data_aggregation', '数据聚合'),
        ('file_association', '文件关联'),
        ('output_generation', '输出生成'),
    ]
    rule_type = models.CharField('规则类型', max_length=30, choices=RULE_TYPE_CHOICES)
    
    # 规则配置
    rule_config = models.JSONField('规则配置', default=dict, help_text='存储具体的规则配置参数')
    
    # 条件配置
    condition_config = models.JSONField('条件配置', default=dict, blank=True, help_text='规则执行的条件')
    
    # 是否启用
    is_active = models.BooleanField('是否启用', default=True)
    
    class Meta:
        db_table = 'core_processing_rule'
        verbose_name = '处理规则'
        verbose_name_plural = '处理规则'
        ordering = ['rule_order']


class DataSourceConfig(BaseModel):
    """数据源配置模型"""
    template = models.ForeignKey(Template, on_delete=models.CASCADE, related_name='data_sources')
    source_name = models.CharField('数据源名称', max_length=100)
    source_order = models.IntegerField('数据源顺序', default=0)
    
    # 数据源类型
    SOURCE_TYPE_CHOICES = [
        ('excel', 'Excel文件'),
        ('csv', 'CSV文件'),
        ('json', 'JSON文件'),
        ('xml', 'XML文件'),
        ('database', '数据库'),
    ]
    source_type = models.CharField('数据源类型', max_length=20, choices=SOURCE_TYPE_CHOICES)
    
    # 读取配置
    READ_DIRECTION_CHOICES = [
        ('horizontal', '水平读取'),
        ('vertical', '垂直读取'),
        ('cross', '交叉读取'),
        ('custom', '自定义读取'),
    ]
    read_direction = models.CharField('读取方向', max_length=20, choices=READ_DIRECTION_CHOICES, default='horizontal')
    
    # 数据区域配置
    data_range = models.JSONField('数据区域', default=dict, blank=True, help_text='配置数据的起始行列、结束行列等')
    
    # 表头配置
    header_config = models.JSONField('表头配置', default=dict, blank=True, help_text='配置表头位置、是否包含表头等')
    
    # 关联键配置
    join_keys = models.JSONField('关联键配置', default=list, blank=True, help_text='配置与其他数据源的关联字段')
    
    # 过滤条件
    filter_conditions = models.JSONField('过滤条件', default=list, blank=True, help_text='配置数据过滤条件')
    
    class Meta:
        db_table = 'core_data_source_config'
        verbose_name = '数据源配置'
        verbose_name_plural = '数据源配置'
        ordering = ['source_order']
        unique_together = [('template', 'source_name')]
        indexes = [
            models.Index(fields=['template', 'source_order']),
            models.Index(fields=['template', 'source_name']),
        ]


class OutputConfig(BaseModel):
    """输出配置模型"""
    template = models.ForeignKey(Template, on_delete=models.CASCADE, related_name='output_configs')
    output_name = models.CharField('输出名称', max_length=100)
    
    # 输出类型
    OUTPUT_TYPE_CHOICES = [
        ('single_file', '单文件输出'),
        ('multiple_files', '多文件输出'),
        ('single_row', '单行输出'),
        ('multiple_rows', '多行输出'),
    ]
    output_type = models.CharField('输出类型', max_length=20, choices=OUTPUT_TYPE_CHOICES)
    
    # 输出格式
    OUTPUT_FORMAT_CHOICES = [
        ('excel', 'Excel格式'),
        ('csv', 'CSV格式'),
        ('json', 'JSON格式'),
        ('xml', 'XML格式'),
    ]
    output_format = models.CharField('输出格式', max_length=20, choices=OUTPUT_FORMAT_CHOICES, default='excel')
    
    # 输出配置
    output_config = models.JSONField('输出配置', default=dict, help_text='配置输出的具体参数')
    
    # 文件名模板
    filename_template = models.CharField('文件名模板', max_length=200, blank=True)
    
    class Meta:
        db_table = 'core_output_config'
        verbose_name = '输出配置'
        verbose_name_plural = '输出配置'
        unique_together = [('template', 'output_name')]
        indexes = [
            models.Index(fields=['template', 'output_name']),
        ]


class ProcessingTask(BaseModel):
    """处理任务模型"""
    STATUS_CHOICES = [
        ('pending', '等待处理'),
        ('processing', '处理中'),
        ('completed', '已完成'),
        ('failed', '处理失败'),
    ]
    
    task_name = models.CharField('任务名称', max_length=200)
    status = models.CharField('状态', max_length=20, choices=STATUS_CHOICES, default='pending')
    progress = models.IntegerField('进度', default=0, help_text='处理进度百分比(0-100)')
    template = models.ForeignKey(Template, on_delete=models.CASCADE, verbose_name='使用模板')
    
    # 处理结果
    result_message = models.TextField('处理结果', blank=True)
    error_message = models.TextField('错误信息', blank=True)
    
    # 处理时间
    started_at = models.DateTimeField('开始时间', null=True, blank=True)
    completed_at = models.DateTimeField('完成时间', null=True, blank=True)
    
    # 文件相关
    result_file = models.FileField('结果文件', upload_to='results/', null=True, blank=True)
    
    class Meta:
        verbose_name = '处理任务'
        verbose_name_plural = '处理任务'
        ordering = ['-created_at']
    
    def __str__(self):
        return f'{self.task_name} - {self.get_status_display()}'
    
    def start_processing(self):
        """开始处理"""
        self.status = 'processing'
        self.started_at = timezone.now()
        self.save()
    
    def complete_processing(self, result_message='', result_file=None):
        """完成处理"""
        self.status = 'completed'
        self.completed_at = timezone.now()
        self.result_message = result_message
        if result_file:
            self.result_file = result_file
        self.save()
    
    def fail_processing(self, error_message=''):
        """处理失败"""
        self.status = 'failed'
        self.completed_at = timezone.now()
        self.error_message = error_message
        self.save()


class UploadedFile(BaseModel):
    """上传文件模型"""
    FILE_TYPE_CHOICES = [
        ('source', '源文件'),
        ('template', '模板文件'),
        ('target', '目标文件'),
        ('po', 'PO文件'),
    ]
    
    original_name = models.CharField('原始文件名', max_length=255)
    file = models.FileField('文件', upload_to='uploads/%Y/%m/%d/')
    file_type = models.CharField('文件类型', max_length=20, choices=FILE_TYPE_CHOICES)
    file_size = models.BigIntegerField('文件大小', default=0)
    source_name = models.CharField('数据源名称', max_length=100, blank=True, help_text='指定文件对应的数据源名称，用于模板处理时的数据源匹配')
    
    # 关联的任务或模板
    task = models.ForeignKey(
        ProcessingTask, 
        on_delete=models.CASCADE, 
        null=True, 
        blank=True,
        related_name='uploaded_files',
        verbose_name='关联任务'
    )
    template = models.ForeignKey(
        Template, 
        on_delete=models.CASCADE, 
        null=True, 
        blank=True,
        related_name='uploaded_files',
        verbose_name='关联模板'
    )
    
    class Meta:
        verbose_name = '上传文件'
        verbose_name_plural = '上传文件'
        ordering = ['-created_at']
    
    def __str__(self):
        return f'{self.original_name} ({self.get_file_type_display()})'


class SystemLog(BaseModel):
    """系统日志模型"""
    LOG_LEVEL_CHOICES = [
        ('DEBUG', 'Debug'),
        ('INFO', 'Info'),
        ('WARNING', 'Warning'),
        ('ERROR', 'Error'),
        ('CRITICAL', 'Critical'),
    ]
    
    level = models.CharField('日志级别', max_length=10, choices=LOG_LEVEL_CHOICES)
    message = models.TextField('日志消息')
    module = models.CharField('模块名称', max_length=100, blank=True)
    function = models.CharField('函数名称', max_length=100, blank=True)
    
    # 关联对象
    task = models.ForeignKey(
        ProcessingTask, 
        on_delete=models.CASCADE, 
        null=True, 
        blank=True,
        related_name='logs',
        verbose_name='关联任务'
    )
    
    class Meta:
        verbose_name = '系统日志'
        verbose_name_plural = '系统日志'
        ordering = ['-created_at']
    
    def __str__(self):
        return f'[{self.level}] {self.message[:50]}'